#![allow(dead_code)]

struct CfgLrn {}

impl CfgLrn {
    fn hello() {
        println!("Cfg! learning!");
    }
}

/// Macro to calculate the sum of multiple values.
///
/// This macro takes any number of arguments, each of which must implement the `Add` trait,
/// and calculates their sum. The arguments are summed in the order they are given.
///
/// # Examples
///
/// ```
/// let result = sum!(1, 2, 3, 4, 5);
/// assert_eq!(result, 15);
/// ```
///
/// # Parameters
///
/// - `...` - A list of values to sum. Each value must implement the `Add` trait.
///
/// # Returns
///
/// Returns the sum of the given values.
///
/// # Panics
///
/// This macro does not directly cause any panics, but if the `Add` implementation for the given
/// values can panic, then this macro can indirectly cause a panic.
///
/// # Safety
///
/// This macro does not use any unsafe code.
///
/// ```
/// #[macro_export]
/// macro_rules! sum {
///     ($($x:expr),+ $(,)?) => {
///         {
///             let mut sum = 0;
///             $(
///                 sum += $x;
///             )*
///             sum
///         }
///     };
/// }
/// ```
#[macro_export]
macro_rules! sum {
    ( $( $x:expr ),* ) => {
        {
            let mut n = 0;
            $(n += $x;)*
            n
        }
    };
}

/// Prints the type of the given variable.
///
/// This function uses the `std::any::type_name` function to print the type of the given variable.
/// The exact contents and format of the string returned by `std::any::type_name` are not specified,
/// other than being a best-effort description of the type.
///
/// # Examples
///
/// ```
/// let data = 5;
/// print_type_of(&data);
/// ```
///
/// # Parameters
///
/// - `_: &T` - A reference to the variable whose type is to be printed.
///
/// # Type Parameters
///
/// - `T` - The type of the variable.
fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>());
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_print_type() {
        let x = 42;
        let y = "hello";
        let z = 3.19;
        print_type_of(&x);
        print_type_of(&y);
        print_type_of(&z);
    }

    #[test]
    /// NOTE: cfg!判断是否
    fn cfg() {
        let x = if cfg!(windows) {
            "windows"
        } else {
            "not windows"
        };
        println!("system is {}", x);
    }

    #[test]
    fn test_sum() {
        let x = sum!(1, 2, 3);
        assert_eq!(x, 6);
    }
}
